#include "Archivo.h"

void escribirArchAlReves( const char* nombre )
{
	long int posFinLinea, posIniLinea;
	int retorno;
	FILE *archivo;

	archivo = fopen ( nombre, "r+b");

	if ( archivo == NULL )
		file_error( "Error al intentar abrir el archivo.\n" );

	retorno = fseek( archivo, 0L, SEEK_END );

	if ( retorno != 0 )
		file_error( "Error al utilizar fseek.\n" );

	posFinLinea = ftell( archivo );

	if ( posFinLinea == -1 )
		file_error( "Error al utilizar ftell.\n" );

	if ( posFinLinea == 0 ) //archivo vacio
		return;

	posFinLinea = posIniLinea = posFinLinea - 1;

	while (  posIniLinea != 0 ) //mientras no llegue al principio del arch
	{
		buscarFinDeLinea ( archivo, &posIniLinea, posFinLinea);
		imprimirLinea ( archivo, posIniLinea, posFinLinea);
		posFinLinea = posIniLinea;
	}

	retorno = fclose( archivo );

	if ( retorno != 0 )
		file_error( "Error al cerrar el archivo.\n" );
}

void imprimirLinea ( FILE* archivo, long int posInicial, long int posFinal)
{
	long int cantALeer, retornoEL;
	int retorno;

	cantALeer = posFinal - posInicial;

	if ( posInicial != 0 ) posInicial++;
	else cantALeer++;

	char *buffer;
	buffer = ( char* ) malloc ( sizeof(char) * (cantALeer) );

	if ( buffer == NULL )
		mem_error();


	retorno = fseek ( archivo, posInicial, SEEK_SET);

	if ( retorno != 0 )
		file_error( "imprimirLinea::Error al utilizar fseek.\n" );

	retornoEL = fread ( buffer, cantALeer, 1, archivo);

	if ( retornoEL != 1 )
		read_error( "imprimirLinea::Error al intentar leer desde el archivo.\n" );

	retornoEL = fwrite ( buffer, cantALeer, 1, stdout);

	if ( retornoEL != 1 )
		write_error();

	free ( buffer );
}

long int getPosicionFinDeLinea(long int cantCharAleer, char *buffer)
{
	long int posicion;
    /* busco de atras para adelante el primer \n q parezca sino, sigo leyendo*/
    for(posicion = cantCharAleer-1;posicion > -1;posicion--)
    {
//    	printf("%c\n", buffer[posicion]);
        if(buffer[posicion] == '\n')
            return posicion;
    }

    return posicion;
}
void buscarFinDeLinea ( FILE* archivo, long int* posInicial, long int posFinal)
{
	long int offset, cantCharAleer, posicion, retornoL;
	int retorno;
	char *buffer;
	offset = 1 ;
	cantCharAleer = TAM_BUFFER;

	while ( offset != 0 ) // o sea, mientras no llego al principio del arch
	{
		offset = posFinal - TAM_BUFFER ;
		//printf ("%li",offset);

		if ( offset < 0 )
		{
			/* si llegue al principio del archivo el offset puede dar menor o igual a cero
			 * y lo que voy a leer en el archivo es menos de lo q TAM_BUFFER */

			offset = 0;
			cantCharAleer = posFinal ;
		}

		buffer = ( char* ) malloc ( sizeof(char) * TAM_BUFFER );

		if ( buffer == NULL )
			mem_error();

		retorno = fseek ( archivo, offset, SEEK_SET);

		if ( retorno != 0 )
			file_error( "buscarFinDeLinea::Error al utilizar fseek.\n" );

		retornoL = fread ( buffer, cantCharAleer, 1, archivo);

		if ( retornoL != 1 )
			read_error( "buscarFinDeLinea::Error al intentar leer desde el archivo.\n" );

	    posicion = getPosicionFinDeLinea( cantCharAleer, buffer);

		if ( posicion != -1)
		{
			(*posInicial) = offset + posicion;
			free( buffer );
			return;
		}
		else
		{
			free( buffer );
			posFinal -= TAM_BUFFER;
		}
	}

	(*posInicial) = 0;
}

